package ar.edu.utn.frba.disenio.model;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import ar.edu.utn.frba.disenio.fechas.Fecha;
import ar.edu.utn.frba.disenio.fechas.Formato;
import ar.edu.utn.frba.disenio.model.exceptions.AsientoNoDisponibleException;
import ar.edu.utn.frba.disenio.model.exceptions.CodigoAsientoInvalidoException;

import com.lanchita.*;
import com.lanchita.excepciones.CodigoErroneoException;
import com.lanchita.excepciones.EstadoErroneoException;

public class Lanchita extends Aerolinea {

	private AerolineaLanchita lanchita;
	
	public Lanchita(AerolineaLanchita interfaz){
		this.lanchita = interfaz;
	}
	
	@Override
	public void comprar(Asiento unAsiento, Usuario unUsuario) {
			String codigo = obtenerCodigo(unAsiento);
			try{
				this.getInterfaz().comprar(codigo);
			} catch(CodigoErroneoException e){
				throw new CodigoAsientoInvalidoException();
			} catch(EstadoErroneoException e){
				throw new AsientoNoDisponibleException(unAsiento.getCodigoDeVuelo(), unAsiento.getNumeroDeAsiento());				
			}
	}
	
	@Override
	public void reservar(Asiento unAsiento, Usuario unUsuario) {
		String codigo = obtenerCodigo(unAsiento);
		String dni = unUsuario.getDni();
		try {
			this.getInterfaz().reservar(codigo,dni);
		} catch (EstadoErroneoException e){
			throw new AsientoNoDisponibleException(unAsiento.getCodigoDeVuelo(), unAsiento.getNumeroDeAsiento());			
		} catch (CodigoErroneoException e){
			throw new CodigoAsientoInvalidoException();
		}
		unAsiento.agregarUsuarioQueReservo(unUsuario);
	}
	
	public Formato getFormatoFechaAsiento() {
		return new Formato("dd/MM/yyyy");
	}
	
	protected String[] parsearCodigo(String unCodigo){
		String delimitador = "[-]";
		String[] codigos = unCodigo.split(delimitador);
		return codigos;
	}
	
	protected Ubicacion parsearUbicacion(String unaUbicacion){
		if (unaUbicacion.equals("P")) { 
			return new Pasillo(); 
		} else if (unaUbicacion.equals("V")) {
			return new Ventana();		
		} else if (unaUbicacion.equals("C")) {
			return new Centro();
		}
		return null;
	}
	
	protected Categoria parsearCategoria(String unaCategoria){
		if (unaCategoria.equals("E")) { 
			return new Ejecutiva(); 
		} else if (unaCategoria.equals("P")) {
			return new Primera();		
		} else if (unaCategoria.equals("T")) {
			return new Turista();
		}
		return null;
	}
	
	public BigDecimal porcentajeAdicional() {
		return new BigDecimal(0.15);
	}

	private String obtenerCodigo(Asiento unAsiento){
		return unAsiento.getCodigoDeVuelo().concat("-").concat(Integer.toString(unAsiento.getNumeroDeAsiento()));
	}
	
	private AerolineaLanchita getInterfaz() {
		return lanchita;
	}

	@Override
	protected List<VueloDirecto> obtenerVuelos(Busqueda unaBusqueda) {
		List<VueloDirecto> vuelos = new ArrayList<VueloDirecto>();
		String codOrigenLanchita = unaBusqueda.getOrigen().getCodigoLanchita();
		String codDestinoLanchita = null;
		if (unaBusqueda.getDestino() != null){
			codDestinoLanchita = unaBusqueda.getDestino().getCodigoLanchita();
		}
		String fechaSalidaBusqueda = this.parsearFecha(unaBusqueda.getFechaSalida());
		String fechaLlegadaBusqueda = null;
		String horaSalidaBusqueda = null;
		String horaLlegadaBusqueda = null;
		Lugar origen = unaBusqueda.getOrigen();
		Lugar destino = unaBusqueda.getDestino();
		String[][] asientos = getInterfaz().asientosDisponibles(codOrigenLanchita, codDestinoLanchita, fechaSalidaBusqueda, horaSalidaBusqueda, fechaLlegadaBusqueda, horaLlegadaBusqueda);
		
		List<Asiento> asientosFormateados = new ArrayList<Asiento>();
		for (String[] unAsientoDisponible : asientos) {
			String[] codigos = this.parsearCodigo(unAsientoDisponible[0]);
			
			int codigoAsiento = Integer.parseInt(codigos[1]);
			BigDecimal precioBase = new BigDecimal(unAsientoDisponible[1]);
			Categoria categoria = this.parsearCategoria(unAsientoDisponible[2]);
			Ubicacion ubicacion = this.parsearUbicacion(unAsientoDisponible[3]);
			
			String codigoVuelo = codigos[0];
			Fecha fechaSalida= this.parsearFechayHoraAerolinea(unAsientoDisponible[10], unAsientoDisponible[6]);
			Fecha fechaLlegada= this.parsearFechayHoraAerolinea(unAsientoDisponible[11], unAsientoDisponible[7]);
			
			Asiento asientoFormateado = new Asiento(codigoVuelo, codigoAsiento, categoria, ubicacion, precioBase, this);
			VueloDirecto vuelo = new VueloDirecto(codigoVuelo, fechaSalida, fechaLlegada, origen, destino, this);
			
			vuelos = this.agregarVueloAListaSiNoExiste(vuelos, vuelo);
			
			asientosFormateados.add(asientoFormateado); 
		}
		
		vuelos = this.asociarAsientosAVuelos(asientosFormateados, vuelos);
		
		return vuelos;
	}
	
	}

